/**
 * 
 */
package br.ufpe.cin.mac.middleware.components.concrete;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import br.ufpe.cin.mac.middleware.components.ConcreteComponent;
import br.ufpe.cin.mac.util.Message;

/**
 * @author obf
 *
 */
public class GZIP extends ConcreteComponent implements GZIPMBean {

	public GZIP() {
		super(GZIP.class.getCanonicalName());
		// TODO Auto-generated constructor stub
	}

	private void sendResponse(Message msg) {
		buffer.put(msg.hashCode(), msg);
		sendNotification(msg, "terP");
	}

	private void sendRequest(Message msg) {
		buffer.put(msg.hashCode(), msg);
		sendNotification(msg, "invU");
	}

	protected void msgManager(Message msg) {
		List ops = msg.readOperations();
		Iterator it = ops.iterator();
		while (it.hasNext()) {

			String op = (String) it.next();
			if (op.equals("sendResponse"))
				sendResponse(msg);

			else if (op.equals("sendRequest"))
				sendRequest(msg);
		}
	}

	public void compre(Message msg) {
		byte[] bMethod = msg.getBMethod();
		ByteArrayOutputStream aout = new ByteArrayOutputStream();
		// write to client
		try {
			GZIPOutputStream gzipout = new GZIPOutputStream(aout);
			gzipout.write(bMethod);
			gzipout.finish();
			byte[] bMCompressed = aout.toByteArray();
			msg.setBMethod(bMCompressed);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void decompre(Message msg) {
		ByteArrayInputStream ain = new ByteArrayInputStream(msg.getBMethod());
		ByteArrayOutputStream aout = new ByteArrayOutputStream();
		final int BUFFER = 2048;
		try {
			GZIPInputStream gzipin = new GZIPInputStream(ain);
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = gzipin.read(data, 0, BUFFER)) != -1) {
				aout.write(data, 0, count);
			}
			msg.setBMethod(aout.toByteArray());

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		Message m = new Message("Sender", "Receiver", "MSGBody");
		m.setMethod("MetodoDeTeste1MetodoDeTeste2MetodoDeTeste3MetodoDeTeste4MetodoDeTeste5MetodoDeTeste6MetodoDeTeste7MetodoDeTeste8MetodoDeTeste9");
		m.setParameter(new Object[] { new Integer(3), new String("teste") });
		m.setSignature(new String[] { Integer.class.getName(),
				String.class.getName() });
		
		
		 GZIP compre = new GZIP();
		 System.out.println("-----------------------------------------");
		 System.out.println("-----------------------------------------");
		 System.out.println("Message before");
		 System.out.println(m.toString());
		 System.out.println("\n-----------------------------------------");
		 System.out.println("-----------------------------------------");
		 compre.compre(m);
		 System.out.println("Message crypto");
		 System.out.println(m.toString());		
		 compre.decompre(m);
		 System.out.println("\n\n-----------------------------------------");
		 System.out.println("-----------------------------------------");
		 System.out.println("Message after");
		 System.out.println(m.toString());
		
		/*
		 try {
			byte[] bMethod = m.getBMethod();
			System.out.println(new String(bMethod));
			
			ByteArrayOutputStream aout = new ByteArrayOutputStream();

			GZIPOutputStream gzipout = new GZIPOutputStream(aout);
			gzipout.write(bMethod);
			gzipout.finish();

			
			byte[] bMCompressed = aout.toByteArray();
			System.out.println(new String(bMCompressed));
			
			ByteArrayInputStream ain = new ByteArrayInputStream(bMCompressed);
			ByteArrayOutputStream aout2 = new ByteArrayOutputStream();
			GZIPInputStream gzipin = new GZIPInputStream(ain);
			final int BUFFER = 2048;
			byte data[] = new byte[BUFFER];
			int count;
			do{
				count = gzipin.read(data, 0, BUFFER);
				if(count != -1){
					aout2.write(data, 0, count);
				}
			}while(count != -1);
			
			byte decompressed[] = aout2.toByteArray();
			System.out.println(new String(decompressed));
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 */

	}

}
